#include "game_task.h"

using namespace std;

namespace {
	template <typename Vec>
	inline bool VecRemove(Vec& vec, typename Vec::value_type val)
	{
		for (typename Vec::iterator iter = vec.begin(); iter != vec.end(); ++iter)
		{
			if (*iter == val)
			{
				*iter = vec.back();
				vec.erase(vec.end() - 1);
				return true;
			}
		}
		return false;
	}	
}

uint32 TaskMgr::GetTaskNum() const
{
	uint32 num = 0;
	for (const auto &v : m_all_task)
	{
		num += v.size();
	}
	return num;
}


uint32 TaskMgr::GetCfgPara(const TaskCfg &cfg, uint32 idx) const
{
	switch (idx)
	{
	default:
		L_ERROR("idx too big. %d", idx); //target_type_info.vec_para_logic 定义的size过大
		return 0;
		break;
	case 0: return cfg.para0; break;
	case 1: return cfg.para1; break;
	case 2: return cfg.para2; break;
	case 3: return cfg.para3; break;
	case 4: return cfg.para4; break;
	}
}


bool TaskMgr::IsLogicOk(TaskParaOpt logic, int64 cur_num, int64 cfg_para) const
{
	if (logic == TaskParaOpt::GREATER)
	{
		if (cur_num >= cfg_para)
		{
			return true;
		}
	}
	else if (logic == TaskParaOpt::LESS)
	{
		if (cur_num <= cfg_para)
		{
			return true;
		}
	}
	else if (logic == TaskParaOpt::EQUAL)
	{
		if (cur_num == cfg_para)
		{
			return true;
		}
	}
	else
	{
		L_ERROR("unknow logic %d", (int)logic);
		return false;
	}
	return false;
}

void TaskMgr::RegTask(BaseTask &task)
{
	if (m_is_updateing)
	{
		L_ERROR("error call CreateTask during updateing");
		return;
	}
	const TaskCfg& cfg = task.GetCfg();
	TaskType t = (TaskType)cfg.task_type;
	if ((uint32_t)t >= (uint32_t)m_all_task.size())
	{
		L_ERROR("illegal task_type=%d", cfg.task_type);
		return;
	}
	VecTask& vec = m_all_task[(uint32_t)t];
	vec.push_back(&task);
}



void TaskMgr::UnregTask(BaseTask& task)
{//注意：可能是BaseTask析构调用的，别调用 BaseTask 的虚函数
	if (m_is_updateing)
	{
		L_ERROR("error call UnRegTask");
		return;
	}

	const TaskCfg& cfg = task.GetCfg();
	TaskType t = (TaskType)cfg.task_type;
	if ((uint32_t)t >= (uint32_t)m_all_task.size())
	{
		L_ERROR("illegal task_type=%d", cfg.task_type);
		return;
	}
	VecTask& vec = m_all_task[(uint32_t)t];

	for (BaseTask* pTask : vec)
	{
		if (&task == pTask)
		{
			VecRemove(vec, pTask);
		}
	}
}
BaseTask::BaseTask(TaskMgr& mgr, const TaskCfg &cfg, int64 num)
	:m_mgr(mgr)
	,m_num(num)
	, m_cfg(cfg)
{
	mgr.RegTask(*this);
}

BaseTask::~BaseTask()
{
	if (TaskMgr* pMgr = m_mgr.Get())//可能mgr先释放，就不需要调用了
	{
		pMgr->UnregTask(*this);
	}
}
